#include "todoTask.h"

#include "MyLogeer.h"
#include <shadow.h>
#include <string>
#include <random>
using namespace std;
void UserLoginSection1::getsetting(string &s, const char *password)
{
    int i, j;
    // 取出salt,i密码字符下标,j记录$出现次数
    for (i = 0, j = 0; password[i] && j != 3; ++i)
    {
        if (password[i] == '$')
        {
            ++j;
        }
    }
    char buff[128] = {0};
    strncpy(buff, password, i);
    s.assign(buff, i);
}

void UserLoginSection1::process()
{
    cout << "login section 1" << endl;
    MySQLClient *mysql = MySQLClient::getInstance();
    if (_packet._type == TASK_TYPE_LOGIN_SECTION1)
    {
        string username = _packet._msg;
        // 存储用户名
        _context.setUsername(username);
        // 查询用户名是否存在取出盐值
        const string sql = "SELECT name,setting from person";
        vector<vector<string>> namesql = mysql->readOperationQuery(sql);
        if (namesql.size())
        {
            // 如果外层size为0说明表格里面没有数据
            LogDebug("namesql=0 error");
            TLV tlv;
            tlv._type = TASK_TYPE_LOGIN_SECTION1_RESP_ERROR;
            tlv._length = 0;
            _conn->sendinLoop(tlv);
            return;
        }
        // 遍历用户名用户名是否存在
        for (int i = 0; i < namesql.size(); ++i)
        {
            string nameinsql = namesql[i][0]; // 查询出来的用户名
            if (nameinsql == username)
            {
                // 说明用户名存在,从数据库中取出盐值
                string setting = namesql[i][1];
                TLV tlv;
                tlv._type = TASK_TYPE_LOGIN_SECTION1_RESP_OK;
                tlv._length = setting.size();
                strncpy(tlv.data, setting.c_str(), tlv._length);
                _conn->sendinLoop(tlv);
                return;
            }
        }
        // 遍历完都没有一致的说明用户名不存在
        TLV tlv;
        tlv._type = TASK_TYPE_LOGIN_SECTION1_RESP_ERROR;
        tlv._length = 0;
        _conn->sendinLoop(tlv);
    }
}

void UserLoginSection2::process()
{
    // 接收到了客户端发送来的密码密文 ，与shadow文件中进行对比
    cout << "login section 2" << endl;
    MySQLClient *mysql = MySQLClient::getInstance();
    if (_packet._type == TASK_TYPE_LOGIN_SECTION2)
    {
        string encrypt = _packet._msg;
        string username = _context.getUsername();
        if (username.empty())
        {
            LogError("未获取到用户名，登录失败");
            // 发送错误响应
            TLV tlv;
            tlv._type = TASK_TYPE_LOGIN_SECTION2_RESP_ERROR;
            tlv._length = 0;
            _conn->sendinLoop(tlv);
            return;
        }
        const string sql = "SELECT encrypt from person where name = '" + username + "'";
        vector<vector<string>> encryptsql = mysql->readOperationQuery(sql);
        if (encrypt == encryptsql[0][0])
        {
            LogInfo("登录成功");
            TLV tlv;
            tlv._type = TASK_TYPE_LOGIN_SECTION2_RESP_OK,
            tlv._length = 0;
            _conn->sendinLoop(tlv);
            return;
        }
        else
        {
            LogInfo("密码错误");
            TLV tlv;
            tlv._type = TASK_TYPE_LOGIN_SECTION2_RESP_ERROR;
            tlv._length = 0;
            _conn->sendinLoop(tlv);
        }
    }
}
// 注册的第一阶段
void UserRegister1::process()
{
    cout << "UserRegister1" << endl;
    string username = _packet._msg;
    _context.setUsername(username);
    MySQLClient *mysql = MySQLClient::getInstance();
    if (_packet._type == TASK_TYPE_REGISTER1)
    {
        vector<vector<string>> result;
        result = mysql->readOperationQuery("select name from person");
        for (auto &filed : result)
        {
            if (filed[1] == username)
            {
                LogInfo("用户名重复");
                TLV tlv;
                tlv._type = TASK_TYPE_REGISTER1_RESP_ERROR;
                tlv._length = 0;
                _conn->sendinLoop(tlv);
                return;
            }
        }
        string salt = generateSalt(4);
        // 保存用户名和盐值
        const string sql = "INSERT INTO person (name,setting) VALUES ('" + username + "'" + "," + "'" + salt + "')";
        mysql->writeOperationQuery(sql);
        TLV tlv;
        tlv._type = TASK_TYPE_REGISTER1_RESP_OK;
        tlv._length = salt.length();
        if (tlv._length > 0)
        {
            int copylength = tlv._length > 1024 ? 1024 : tlv._length;
            strncpy(tlv.data, salt.c_str(), copylength);
            tlv.data[copylength] = '\0';
        }
        else
        {
            tlv.data[0] = '\0';
        }
        _conn->sendinLoop(tlv);
        return;
    }
}
void UserRegister2::process()
{
    cout << "UserRegister2" << endl;
    if (_packet._type == TASK_TYPE_REGISTER2)
    {
        MySQLClient *mysql = MySQLClient::getInstance();
        string encrypt = _packet._msg;
        string username = _context.getUsername();
        // 保存密文
        const string sql = "UPDATE person SET encrypt = ' " + encrypt + "'" + "where name = '" + username + "'";
        bool ret = mysql->writeOperationQuery(sql);
        if (ret == false)
        {
            TLV tlv;
            tlv._type = TASK_TYPE_REGISTER1_RESP_ERROR;
            tlv._length = 0;
            _conn->sendinLoop(tlv);
            LogError("mysql error");
            return;
        }
        TLV tlv;
        tlv._type = TASK_TYPE_REGISTER2_RESP_OK;
        tlv._length = 0;
        _conn->sendinLoop(tlv);
    }
}
string UserRegister1::generateSalt(int length)
{
    const char *chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    string salt;
    random_device rd;
    unsigned int seed = rd();
    mt19937 rng(seed);
    for (int i = 0; i < length; ++i)
    {
        salt[i] = chars[rng() % strlen(chars)];
    }
    return salt;
}
